
#include "SpriteEffect.h"
#include "SpriteEffectManager.h"

SpriteEffect::SpriteEffect(RenderableEntity* _entity, float _fDuration, bool _bEnabled, bool _bLoop)
{
    m_entity = _entity;
    m_fDuration = _fDuration;
    m_bEnabled = _bEnabled;
    m_bLoop = _bLoop;
    
    m_fElapsedTime = 0;
    m_fSpeed = 1.0f;

	m_eEaseMode = EASE_NONE;
	
    SpriteEffectManager::instance().addEffect(this);
}

void SpriteEffect::reset()
{
    m_fElapsedTime = 0;
}

void SpriteEffect::setEnabled(bool _bEnabled)
{
    if(_bEnabled && !m_bEnabled)
    {
        m_bEnabled = true;
    }
    else
    {
        m_bEnabled = _bEnabled;
    }
    
    enableEffect(_bEnabled);
}

void SpriteEffect::start(bool _bReset)
{
    if(_bReset)
        reset();
    
    setEnabled(true);
}

void SpriteEffect::update(float dt)
{
    if(!m_bEnabled)
        return;
    
    m_fElapsedTime += (dt * m_fSpeed);
    if(m_fElapsedTime >= m_fDuration)
    {
        if(m_bLoop)
        {
            m_fElapsedTime = fmodf(m_fElapsedTime, m_fDuration);
        }
        else
        {
            updateEffect(1.0f);
            setEnabled(false);
            return;
        }
    }
    
    float x = m_fElapsedTime / m_fDuration;
    updateEffect(getPerc(x));
}

bool SpriteEffect::isFinished()
{
    return !m_bEnabled || m_fElapsedTime >= m_fDuration;
}

bool SpriteEffect::isEnabled()
{
    return m_bEnabled;
}

void SpriteEffect::setDuration(float _fDuration)
{
    m_fDuration = _fDuration;
}

float SpriteEffect::getDuration()
{
    return m_fDuration;
}

void SpriteEffect::setLoop(bool _bLoop)
{
    m_bLoop = _bLoop;
}

bool SpriteEffect::isLoop()
{
    return m_bLoop;
}

void SpriteEffect::setSpeed(float _fSpeed)
{
    m_fSpeed = _fSpeed;
}

void SpriteEffect::setEaseMode(eEaseMode _eEaseMode)
{
    m_eEaseMode = _eEaseMode;
}

float SpriteEffect::getPerc(float t)
{
	switch(m_eEaseMode)
	{
		case EASE_NONE:
			return t;
		case EASE:
			return ease(t);
		case EASE_IN:
			return easeIn(t);
		case EASE_OUT:
			return easeOut(t);
	}
}

float SpriteEffect::ease(float T)
{
    float T2 = T * T;
    float T3 = T * T2;

    return (3.0f * (1.0f - T) * T2) + T3;
}

float SpriteEffect::easeOut(float T)
{
    float T2 = T * T;
    float T3 = T * T2; 

    return -T3 + T2 + T;
}

float SpriteEffect::easeIn(float T)
{
    float T2 = T * T;
    float T3 = T * T2;

    return (-1.0f * T3) + (2.0f * T2);
}
